package com.wuzhao.resume.common.util;

import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.parser.PdfTextExtractor;
import com.wuzhao.resume.entity.ResumeDO;
import com.wuzhao.resume.entity.ResumeFile;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.extractor.WordExtractor;
import org.apache.poi.xwpf.extractor.XWPFWordExtractor;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.springframework.http.HttpRequest;
import org.springframework.util.ResourceUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * @author: Yu Feifei
 * @since: 2020-10-19 15:04
 * @description:
 * @version: 1.0
 */
public class FileUtils {

    private static Map<String, List<String>> keyPools;
    private static List<String> replaceKey;
    private static List<String> cityList;


    static {
        keyPools = new HashMap<>();
        //姓名
        List<String> nameList = new ArrayList<>();
        nameList.add("姓名");
        nameList.add("名:");
        nameList.add("名");
        keyPools.put("name", nameList);

        //联系方式
        List<String> numberList = new ArrayList<>();
        numberList.add("联系方式");
        numberList.add("手机");
        numberList.add("机");
        numberList.add("电话");
        keyPools.put("mobileNumber", numberList);

        //地区
        List<String> districtList = new ArrayList<>();
        districtList.add("住址");
        districtList.add("居住地");
        districtList.add("址");
        keyPools.put("district", districtList);

        //招聘岗位
        List<String> jobList = new ArrayList<>();
        jobList.add("职位名称");
        jobList.add("求职意向");
        jobList.add("岗位");
        jobList.add("职位");
        jobList.add("职能");
        keyPools.put("job", jobList);

        //期望薪资
        List<String> salaryList = new ArrayList<>();
        salaryList.add("目标薪资");
        salaryList.add("期望薪资");
        salaryList.add("期望月薪");
        salaryList.add("薪资");
        salaryList.add("月薪");
        keyPools.put("salary", salaryList);

        cityList = new ArrayList<String>();

        cityList.add("北京");
        cityList.add("上海");
        cityList.add("天津");
        cityList.add("重庆");

        cityList.add("黑龙江");
        cityList.add("吉林");
        cityList.add("辽宁");
        cityList.add("内蒙古");

        cityList.add("河北");
        cityList.add("河南");
        cityList.add("山东");
        cityList.add("山西");

        cityList.add("江苏");
        cityList.add("安徽");
        cityList.add("陕西");
        cityList.add("宁夏");

        cityList.add("甘肃");
        cityList.add("青海");
        cityList.add("湖北");
        cityList.add("湖南");

        cityList.add("浙江");
        cityList.add("江西");
        cityList.add("福建");
        cityList.add("贵州");

        cityList.add("四川");
        cityList.add("广东");
        cityList.add("广西");
        cityList.add("云南");

        cityList.add("海南");
        cityList.add("新疆");
        cityList.add("西藏");

        cityList.add("香港");
        cityList.add("澳门");
        cityList.add("台湾");


        //替换关键字
      /*  replaceKey = new ArrayList<String>();
        replaceKey.add(":");
        replaceKey.add("：");
        replaceKey.add("；");
        replaceKey.add(";");*/

    }

    /**
     * 解析doc文件
     *
     * @param filePath
     * @return
     */
    public static Map readWordDoc(String filePath) {
        FileInputStream fis = null;
        StringBuilder result = null;
        try {
            fis = new FileInputStream(filePath);
            result = new StringBuilder();
            HWPFDocument doc = new HWPFDocument(fis);
            WordExtractor re = new WordExtractor(doc);
            result.append(re.getText());
            fis.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return ParseContent(result.toString());
    }


    /**
     * 解析docx文件
     *
     * @param filePath
     * @return
     */
    public static Map readWordDocx(String filePath) {
        XWPFWordExtractor extractor = null;
        FileInputStream fis = null;
        try {
            File docFile = new File(filePath);

            fis = new FileInputStream(docFile);

            XWPFDocument xdoc = new XWPFDocument(fis);
            extractor = new XWPFWordExtractor(xdoc);
            fis.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return ParseContent(extractor.getText());
    }


    /**
     * 解析pdf文件
     *
     * @param filePath
     * @return
     */
    public static Map readPdf(String filePath) {
        PdfReader reader = null;//PDF读取器
        StringBuffer buffer = null;
        try {
            reader = new PdfReader(filePath);
            buffer = new StringBuffer();
            for (int i = 1; i <= reader.getNumberOfPages(); i++) {
                buffer.append(PdfTextExtractor.getTextFromPage(reader, i)); // 读取PDF中第n页（用哪一页就写几）的文档内容，并转成String
                break;//只读取第一页
            }
            reader.close();
            return ParseContent(buffer.toString());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                reader.close();
            }
        }
        return null;
    }


    /**
     * 解析文件
     *
     * @param content
     * @return
     */
    public static Map<String, String> ParseContent(String content) {
        //1、截取前500个字符
        String subResult = content.substring(0, 300);
        HashMap<String, String> ParseMap = new HashMap<>();
        //2、开始查找：姓名
        String parseName = null;
        List<String> nameList = keyPools.get("name");
        for (String name : nameList) {
            //int i = subResult.indexOf(name);
            if (subResult.indexOf(name) > -1) { //找到,截取后7位
                parseName = subResult.substring(subResult.indexOf(name) + name.length() + 1, subResult.indexOf(name) + 7).trim();
                parseName = getNameStr(parseName.replaceAll(" ", ""));
                break;//找到跳出
            }
        }
        ParseMap.put("name", parseName);

        //2、开始查找：电话号码
        String parseNumber = null;
        List<String> numberList = keyPools.get("mobileNumber");
        for (String number : numberList) {
            if (subResult.indexOf(number) > -1) { //找到,截取后13位
                parseNumber = subResult.substring(subResult.indexOf(number) + number.length() + 1, subResult.indexOf(number) + 20).trim();
                parseNumber = getPhoneNumber(parseNumber);
                break;//找到跳出
            }
        }
        ParseMap.put("mobileNumber", parseNumber);

        //3、开始查找：地区
        String parseDistrict = null;
        List<String> districtList = keyPools.get("district");
        for (String district : districtList) {
            if (subResult.indexOf(district) > -1) { //找到,截取后20位
                parseDistrict = subResult.substring(subResult.indexOf(district) + district.length() + 1, subResult.indexOf(district) + 20).trim();
                for (String city : cityList) {
                    if (parseDistrict.indexOf(city) != -1) { //匹配到省市
                        parseDistrict = city;
                        break;
                    }
                }
                break;
            }

        }

        ParseMap.put("district", parseDistrict);
        //4、开始查找：招聘岗位
        String parseJob = null;
        List<String> jobList = keyPools.get("job");
        for (String job : jobList) {
            if (subResult.indexOf(job) > -1) { //找到,岗位截取后10位
                parseJob = subResult.substring(subResult.indexOf(job) + job.length() + 1, subResult.indexOf(job) + 15).trim();
                break;//找到跳出
            }
        }
        ParseMap.put("job", parseJob);

        //5、开始查找：期望薪资
        String parseSalary = null;
        List<String> salaryList = keyPools.get("salary");
        for (String salary : salaryList) {
            if (subResult.indexOf(salary) > -1) { //找到,期望薪资截取后10位
                parseSalary = subResult.substring(subResult.indexOf(salary) + salary.length() + 1, subResult.indexOf(salary) + 8).trim();
                break;//找到跳出
            }
        }
        ParseMap.put("salary", parseSalary);

        return ParseMap;
    }

    /**
     * 解析文件主入口
     *
     * @param filePath
     * @return
     */
    public static Map readWordOrPdf(String filePath) {
        //判断是word,还是pdf
        String suffix = filePath.substring(filePath.lastIndexOf(".") + 1);
        Map result = null;
        switch (suffix) {
            case "doc":
                //解析doc文件
                result = readWordDoc(filePath);
                break;
            case "docx":
                //解析docx文件
                result = readWordDocx(filePath);
                break;
            case "pdf":
                result = readPdf(filePath);
                break;
            default:
                return null;
        }
        return result;
    }


    /**
     * 测试代码
     *
     * @param args
     */
    public static void main(String[] args) {
        String text = "java工程师-余飞飞_河南_17625510895_10k";
        String text1 = "余飞飞—java_河南_17625510895+13k";
        String text3 = "张三—开发_河南--11K";
        String text4 = "java(开发)工程师_王明_上海_18721564427_11k";
        System.out.println(parseText(text4));
    }


    /**
     * 姓名_岗位_地区_电话_薪资
     * 解析文本数据，根据特殊字符分割
     *
     * @param fileName
     * @return
     */
    public static Map<String, String> parseText(String fileName) {
        String regEx = "(_|-|—|\\.){1}";
        //1、分割字符
        Map<String, String> parseMap = new HashMap<>();
        try {
            String[] splitResult = fileName.split(regEx);
            parseMap.put("job", splitResult[0]);
            parseMap.put("name", splitResult[1]);
            parseMap.put("district", splitResult[2]);
            parseMap.put("mobileNumber", splitResult[3]);
            parseMap.put("salary", splitResult[4]);
            //2、验证手机号等
            String mobileNumber = parseMap.get("mobileNumber");
            if (mobileNumber != null) {
                mobileNumber = getPhoneNumber(mobileNumber);
            } else {
                mobileNumber = "手机号有误请检查！";
            }
            parseMap.put("mobileNumber", mobileNumber);
        } catch (Exception e) {
            e.printStackTrace();
        }
        //3、封装数据返回
        return parseMap;
    }


    /**
     * 删除单个文件
     *
     * @throws Exception
     */
    public static void deleteFile(ResumeFile resumeFile) {
        try {
            String realPath = resumeFile.getFilePath();
            File file = new File(realPath);
            if (!file.exists()) {
                throw new FileNotFoundException();
            } else {
                if (file.isFile()) {
                    file.delete();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 过滤中文文本
     *
     * @param text 文本
     * @throws Exception
     */
    public static String getNameStr(String text) {
        String res = "";
        String pattern = "(^[^\\u4e00-\\u9fa5]*)([\\u4e00-\\u9fa5]{2,4})([^\\u4e00-\\u9fa5]*$)";
        Pattern r = Pattern.compile(pattern);
        Matcher m = r.matcher(text);
        while (m.find()) {
            res = m.group(2);
        }
        return res;
    }

    /**
     * 过滤中文文本
     *
     * @param text 文本
     * @throws Exception
     */
    public static String getChinaStr(String text) {
        String res = "";
        String pattern = "(^[^\\u4e00-\\u9fa5]*)([\\u4e00-\\u9fa5]+)([^\\u4e00-\\u9fa5]*$)";
        Pattern r = Pattern.compile(pattern);
        Matcher m = r.matcher(text);
        while (m.find()) {
            res = m.group(2);
        }
        return res;
    }

    /**
     * 过滤手机号码
     *
     * @param text 文本
     * @throws Exception
     */
    public static String getPhoneNumber(String text) {
        String res = "";
        String pattern = "^1[0-9]{10}$";
        Pattern r = Pattern.compile(pattern);
        Matcher m = r.matcher(text);
        while (m.find()) {
            res = m.group(0);
        }
        return res;
    }

    /**
     * 产生UUID随机字符串工具类
     *
     * @return
     */
    public static String getUuid() {
        return UUID.randomUUID().toString().replace("-", "");
    }

    /**
     * 上传文件
     *
     * @param file
     * @throws IOException
     */
    public static Map<String, String> upload(MultipartFile file,String basePath) throws IOException {
        String oldName = file.getOriginalFilename();
        String newName = getUuid() + oldName.substring(oldName.indexOf("."));
        File uploadFile = new File(basePath + "/upload/" + newName);
        File parentFile = uploadFile.getParentFile();
        if (!parentFile.exists()) { //创建父目录
            parentFile.mkdirs();
        }
        file.transferTo(uploadFile);
        Map<String, String> resultMap = new HashMap<String, String>();
        resultMap.put("newName", newName);
        resultMap.put("oldName", oldName);
        resultMap.put("path", uploadFile.getAbsolutePath());
        return resultMap;
    }

    /**
     * 下载文件
     *
     * @param id
     * @param response
     * @throws Exception
     */
    public static void download(ResumeDO resumeDO, ResumeFile resumeFile, Integer id, HttpServletResponse response) throws
            IOException {
        //从数据库中获取绝对路径
        String realPath = resumeFile.getFilePath();

        File file = new File(realPath);

        if (!file.exists()) {
            throw new FileNotFoundException();
        }

        byte[] bytes = new byte[1024 * 1024];
        BufferedInputStream bufferedInputStream = null;
        OutputStream outputStream = null;
        FileInputStream fileInputStream = null;

        try {
            fileInputStream = new FileInputStream(file);
            bufferedInputStream = new BufferedInputStream(fileInputStream);
            //response.setContentType(MediaType.APPLICATION_OCTET_STREAM.toString());
            response.addHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(resumeFile.getOldName(), "UTF-8"));
            outputStream = response.getOutputStream();
            int length;
            while ((length = bufferedInputStream.read(bytes)) != -1) {
                outputStream.write(bytes, 0, length);
            }
            outputStream.flush();
        } catch (IOException e) {
            throw new IOException("IO异常");
        } finally {
            if (bufferedInputStream != null) {
                bufferedInputStream.close();
            }
            if (outputStream != null) {
                outputStream.close();
            }
            if (fileInputStream != null) {
                fileInputStream.close();
            }
        }

    }

    /**
     * 批量下载并打成zip包
     *
     * @param resumeFileAll
     * @param response
     * @throws IOException
     */
    public static void downloadAll(String zipName, List<ResumeFile> resumeFileAll, HttpServletResponse response) throws
            IOException {
        FileInputStream fis = null;
        ZipOutputStream out = null;
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
            //写入数组中
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            out = new ZipOutputStream(os); //zip文件写到内存中


            File[] resumeFiles = new File[resumeFileAll.size()]; //需要打包的文件数组
            ArrayList<String> oldNameList = new ArrayList<>();
            //创建文件集合
            for (int i = 0; i < resumeFileAll.size(); i++) {
                resumeFiles[i] = new File(resumeFileAll.get(i).getFilePath());
                oldNameList.add(resumeFileAll.get(i).getOldName()); ///获取上传时的文件名
            }
            byte[] buff = new byte[1024 * 1024];
            for (int i = 0; i < resumeFiles.length; i++) {
                fis = new FileInputStream(resumeFiles[i]);
                //创建压缩文件中的条目
                ZipEntry entry = new ZipEntry(oldNameList.get(i));
                //将创建好的条目加入到压缩文件中
                out.putNextEntry(entry);
                //写入当前条目所对应的具体内容
                int len = 0;
                while ((len = fis.read(buff)) != -1) {
                    out.write(buff, 0, len);
                }
                out.flush();
            }
            out.close();
            fis.close();

            byte[] bytes = new byte[1024 * 1024];

            byte[] content = os.toByteArray();
            InputStream is = new ByteArrayInputStream(content); //从内存中读取zip文件
            bis = new BufferedInputStream(is);

            response.addHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(zipName + ".zip", "UTF-8"));
            bos = new BufferedOutputStream(response.getOutputStream());
            int length;
            while ((length = bis.read(bytes)) != -1) {
                bos.write(bytes, 0, length);
                bos.flush();
            }
            bos.close();
            bis.close();
        } catch (IOException e) {
            throw new IOException("IO异常");
        } finally {
            if (bos != null) {
                bos.close();
            }
            if (bis != null) {
                bis.close();
            }
            if (out != null) {
                out.close();
            }
            if (fis != null) {
                fis.close();
            }
        }

    }

}
